﻿using System;
using System.Runtime.CompilerServices;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using TrafficWatcher.Infrastructure;
using TrafficWatcher.Models;
using TrafficWatcher.ViewModels.Helpers;
using TrafficWatcher.Views;

namespace TrafficWatcher.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        private TimeSpan duration = TimeSpan.Zero;

        private readonly Settings settings;
        private readonly IDirectionDurationService directionDurationService;
        private string currentDirectionsProviderName;

        public MainViewModel(Settings settings, IEnvironmentContext environmentContext, IDirectionDurationService directionDurationService)
        {
            this.settings = settings;
            this.settings.SettingsChanged += (_, __) => CurrentDirectionsProviderName = settings.CurrentDirectionsProvider.Name;

            this.directionDurationService = directionDurationService;
            this.directionDurationService.DurationChanged += (_, __) => Duration = directionDurationService.Duration;

            CurrentDirectionsProviderName = this.settings.CurrentDirectionsProvider.Name;

            OpenDirectionCommand = new RelayCommand(() => environmentContext.OpenUrl(settings.CurrentDirectionsProvider.GetUri(settings.Start, settings.Finish)));
            ExitCommand = new RelayCommand(OnShutdownRequested);
            OpenSettingsCommand = new RelayCommand(() => WindowService.OpenWindow(typeof(SettingsWindow)));
        }

        public TimeSpan Duration
        {
            get { return duration; }
            private set { SetProperty(ref duration, value); }
        }

        public string CurrentDirectionsProviderName
        {
            get { return currentDirectionsProviderName; }
            private set { SetProperty(ref currentDirectionsProviderName, value); }
        }
        
        public event EventHandler ShutdownRequested;

        public RelayCommand OpenDirectionCommand { get; private set; }
        public RelayCommand OpenSettingsCommand { get; private set; }
        public RelayCommand ExitCommand { get; private set; }

        protected virtual void OnShutdownRequested()
        {
            var handler = ShutdownRequested;
            if (handler != null) handler(this, EventArgs.Empty);
        }

        private void SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (!Equals(storage, value))
            {
                storage = value;
                RaisePropertyChanged(propertyName);
            }
        }
    }
}
